use crate::generator::{FileGenerator, GenerationContext};
use crate::templates::TemplateManager;
use anyhow::{Context, Result};
use colored::*;
use indicatif::{ProgressBar, ProgressStyle};
use std::fs;
use std::path::Path;

/// 核心生成器
/// 负责协调整个项目生成过程
pub struct Generator {
    template_manager: TemplateManager,
    file_generator: FileGenerator,
}

impl Generator {
    /// 创建新的生成器实例
    pub fn new() -> Self {
        Self { template_manager: TemplateManager::new(), file_generator: FileGenerator::new() }
    }

    /// 生成扩展项目
    pub async fn generate(
        &self,
        context: &GenerationContext,
    ) -> Result<()> {
        println!("{}", "🚀 开始生成扩展项目...".bold().cyan());
        println!();

        // 创建进度条
        let pb = ProgressBar::new(100);
        pb.set_style(
            ProgressStyle::default_bar()
                .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}% {msg}")
                .unwrap()
                .progress_chars("#>-"),
        );

        // 1. 准备输出目录 (10%)
        pb.set_message("准备输出目录...");
        self.prepare_output_directory(&context.output_dir).context("准备输出目录失败")?;
        pb.set_position(10);

        // 2. 生成基础文件 (30%)
        pb.set_message("生成基础项目文件...");
        self.generate_base_files(context).await.context("生成基础文件失败")?;
        pb.set_position(30);

        // 3. 生成各层文件 (80%)
        let layers = &context.enabled_layers;
        let step_size = 50 / layers.len().max(1) as u64;

        for (i, layer) in layers.iter().enumerate() {
            pb.set_message(format!("生成 {:?} 层文件...", layer));
            self.generate_layer_files(context, layer).await.with_context(|| format!("生成 {:?} 层文件失败", layer))?;
            pb.set_position(30 + (i + 1) as u64 * step_size);
        }

        // 4. 生成文档和配置 (100%)
        pb.set_message("生成文档和配置文件...");
        self.generate_documentation(context).await.context("生成文档失败")?;
        pb.set_position(100);

        pb.finish_with_message("✅ 项目生成完成!");
        println!();

        Ok(())
    }

    /// 准备输出目录
    fn prepare_output_directory(
        &self,
        output_dir: &Path,
    ) -> Result<()> {
        if output_dir.exists() {
            // 如果目录存在，清空内容
            fs::remove_dir_all(output_dir).with_context(|| format!("无法删除现有目录: {}", output_dir.display()))?;
        }

        // 创建输出目录
        fs::create_dir_all(output_dir).with_context(|| format!("无法创建目录: {}", output_dir.display()))?;

        Ok(())
    }

    /// 生成基础项目文件
    async fn generate_base_files(
        &self,
        context: &GenerationContext,
    ) -> Result<()> {
        // 生成 Cargo.toml
        self.file_generator
            .generate_from_template(&self.template_manager.get_cargo_toml_template(), &context.output_dir.join("Cargo.toml"), context)
            .await
            .context("生成 Cargo.toml 失败")?;

        // 生成 src/lib.rs
        let src_dir = context.output_dir.join("src");
        fs::create_dir_all(&src_dir)?;

        self.file_generator
            .generate_from_template(&self.template_manager.get_lib_rs_template(), &src_dir.join("lib.rs"), context)
            .await
            .context("生成 lib.rs 失败")?;

        // 生成 README.md
        self.generate_readme(context).await.context("生成 README.md 失败")?;

        Ok(())
    }

    /// 生成各层文件
    async fn generate_layer_files(
        &self,
        context: &GenerationContext,
        layer: &crate::cli::LayerType,
    ) -> Result<()> {
        use crate::cli::LayerType;

        let src_dir = context.output_dir.join("src");

        match layer {
            LayerType::Nodes => {
                self.generate_nodes_layer(context, &src_dir).await?;
            },
            LayerType::Plugins => {
                self.generate_plugins_layer(context, &src_dir).await?;
            },
            LayerType::Commands => {
                self.generate_commands_layer(context, &src_dir).await?;
            },
            LayerType::Router => {
                self.generate_router_layer(context, &src_dir).await?;
            },
        }

        Ok(())
    }

    /// 生成 Nodes 层文件
    async fn generate_nodes_layer(
        &self,
        context: &GenerationContext,
        src_dir: &Path,
    ) -> Result<()> {
        let nodes_dir = src_dir.join("nodes");
        fs::create_dir_all(&nodes_dir)?;

        // 生成 nodes/mod.rs
        self.file_generator.generate_from_template(&self.template_manager.get_nodes_mod_template(), &nodes_dir.join("mod.rs"), context).await?;

        // 生成 nodes/node_definitions.rs
        self.file_generator
            .generate_from_template(
                &self.template_manager.get_node_definitions_template(),
                &nodes_dir.join(format!("{}_definitions.rs", context.names.snake)),
                context,
            )
            .await?;

        // 生成 nodes/fields.rs
        self.file_generator.generate_from_template(&self.template_manager.get_fields_template(), &nodes_dir.join("fields.rs"), context).await?;

        Ok(())
    }

    /// 生成 Plugins 层文件
    async fn generate_plugins_layer(
        &self,
        context: &GenerationContext,
        src_dir: &Path,
    ) -> Result<()> {
        let plugins_dir = src_dir.join("plugins");
        fs::create_dir_all(&plugins_dir)?;

        // 生成 plugins/mod.rs
        self.file_generator.generate_from_template(&self.template_manager.get_plugins_template(), &plugins_dir.join("mod.rs"), context).await?;

        Ok(())
    }

    /// 生成 Commands 层文件
    async fn generate_commands_layer(
        &self,
        context: &GenerationContext,
        src_dir: &Path,
    ) -> Result<()> {
        let commands_dir = src_dir.join("command");
        fs::create_dir_all(&commands_dir)?;

        // 生成 command/mod.rs
        self.file_generator.generate_from_template(&self.template_manager.get_commands_template(), &commands_dir.join("mod.rs"), context).await?;

        Ok(())
    }

    /// 生成 Router 层文件
    async fn generate_router_layer(
        &self,
        context: &GenerationContext,
        src_dir: &Path,
    ) -> Result<()> {
        let router_dir = src_dir.join("router");
        fs::create_dir_all(&router_dir)?;

        // 生成 router/mod.rs
        self.file_generator.generate_from_template(&self.template_manager.get_router_mod_template(), &router_dir.join("mod.rs"), context).await?;

        // 生成 router/handlers.rs
        self.file_generator.generate_from_template(&self.template_manager.get_handlers_template(), &router_dir.join("handlers.rs"), context).await?;

        // 生成 router/dto.rs
        self.file_generator.generate_from_template(&self.template_manager.get_dto_template(), &router_dir.join("dto.rs"), context).await?;

        Ok(())
    }

    /// 生成 README.md
    async fn generate_readme(
        &self,
        context: &GenerationContext,
    ) -> Result<()> {
        let readme_content = format!(
            r#"# {}

{}

## 项目结构

这是一个基于 Price-RS 框架的扩展项目，采用标准的四层架构：

{}

## 快速开始

### 编译项目

```bash
cargo build
```

### 运行测试

```bash
cargo test
```

### 集成到工作空间

将此项目添加到根目录的 `Cargo.toml` 中：

```toml
[workspace]
members = [
    # ... 其他成员
    "{}",
]
```

{}

## 开发指南

### 主要组件

{}

### TODO 清单

生成的代码包含以下需要完善的部分：

- [ ] 完善业务逻辑实现
- [ ] 添加具体的数据验证规则
- [ ] 实现实际的计算算法
- [ ] 添加错误处理和日志
- [ ] 编写更全面的测试用例

## 许可证

本项目采用 MIT 许可证。

---

由 [Price-RS Extension Generator]({}) 自动生成
"#,
            context.project_name(),
            context.description,
            self.generate_architecture_description(context),
            context.output_dir.file_name().unwrap().to_str().unwrap(),
            self.generate_usage_instructions(context),
            self.generate_component_descriptions(context),
            "https://github.com/your-org/price-rs/tools/extension-generator"
        );

        fs::write(context.output_dir.join("README.md"), readme_content)?;

        Ok(())
    }

    /// 生成架构描述
    fn generate_architecture_description(
        &self,
        context: &GenerationContext,
    ) -> String {
        let mut description = String::new();

        for layer in &context.enabled_layers {
            let layer_desc = match layer {
                crate::cli::LayerType::Nodes => "- **📄 Nodes 层**: 数据结构定义和字段验证",
                crate::cli::LayerType::Plugins => "- **🔌 Plugins 层**: 业务逻辑实现和事务处理",
                crate::cli::LayerType::Commands => "- **⚡ Commands 层**: CRUD 操作和命令处理",
                crate::cli::LayerType::Router => "- **🌐 Router 层**: HTTP API 接口和路由管理",
            };
            description.push_str(layer_desc);
            description.push('\n');
        }

        description
    }

    /// 生成使用说明
    fn generate_usage_instructions(
        &self,
        context: &GenerationContext,
    ) -> String {
        if context.has_layer(&crate::cli::LayerType::Router) {
            format!(
                r#"
### API 使用

启动服务后，可以通过以下端点访问 {} 功能：

- `GET /{}/` - 获取{}列表
- `POST /{}/` - 创建新{}
- `GET /{}/:id` - 获取指定{}
- `PUT /{}/:id` - 更新指定{}
- `DELETE /{}/:id` - 删除指定{}
- `POST /{}/calc/calculate` - 执行{}计算

详细的 API 文档请参考 `src/router/` 目录下的文件。
"#,
                context.description,
                context.names.kebab,
                context.description,
                context.names.kebab,
                context.description,
                context.names.kebab,
                context.description,
                context.names.kebab,
                context.description,
                context.names.kebab,
                context.description,
                context.names.kebab,
                context.description
            )
        } else {
            format!(
                r#"
### 库使用

```rust
use {}::*;

// 创建插件实例
let plugin = {}::new();

// 使用节点定义
let container = {}Factory::create_container("测试数据".to_string());
```
"#,
                context.project_name().replace('-', "_"),
                context.plugin_struct_name(),
                context.node_prefix()
            )
        }
    }

    /// 生成组件描述
    fn generate_component_descriptions(
        &self,
        context: &GenerationContext,
    ) -> String {
        let mut descriptions = String::new();

        for layer in &context.enabled_layers {
            let layer_desc = match layer {
                crate::cli::LayerType::Nodes => {
                    format!("- **{}ContainerNode**: 容器节点，表示整体数据结构\n- **{}RowNode**: 行节点，表示具体数据项\n- **{}Factory**: 工厂类，用于创建节点实例", 
                        context.node_prefix(), context.node_prefix(), context.node_prefix())
                },
                crate::cli::LayerType::Plugins => {
                    format!("- **{}**: 主要插件类，实现业务逻辑", context.plugin_struct_name())
                },
                crate::cli::LayerType::Commands => {
                    format!(
                        "- **Insert{}**: 插入命令\n- **Update{}**: 更新命令\n- **Delete{}**: 删除命令\n- **Calculate{}**: 计算命令",
                        context.node_prefix(),
                        context.node_prefix(),
                        context.node_prefix(),
                        context.node_prefix()
                    )
                },
                crate::cli::LayerType::Router => {
                    format!("- **{}Router**: 路由定义\n- **handlers**: HTTP 处理器\n- **dto**: 数据传输对象", context.node_prefix())
                },
            };
            descriptions.push_str(&layer_desc);
            descriptions.push_str("\n");
        }

        descriptions
    }

    /// 生成文档和配置文件
    async fn generate_documentation(
        &self,
        _context: &GenerationContext,
    ) -> Result<()> {
        // 这里可以生成更多的文档文件，如：
        // - CHANGELOG.md
        // - LICENSE
        // - .gitignore
        // - examples/

        Ok(())
    }
}

impl Default for Generator {
    fn default() -> Self {
        Self::new()
    }
}
